import datetime
import json
import logging
import os
import time
import base64
from Crypto.Cipher import AES
from django.utils import timezone
from django.conf import settings
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from bike.auth import BikeJWT
from bike.models import Staff, Violation
from bike.models import Plate
from bike.models import Car
from bike.models import Student
from bike.models import Teacher
from bike.serializers import CarSerl, PlateSerl, StaffSerl, StudentSerl, TeacherSerl, ViolationSerl, ViolationListSerl

logger = logging.getLogger("log")


def add_to_16(value):
    # 中文gbk时占2个字节，utf-8占3个字节
    value = value.encode("utf-8")
    while len(value) % 16 != 0:
        value += "\0".encode()
    return value


def encrypt(plaintext):
    key = "c07fc7174561aa91"
    iv = "c90866af49c1b68a"
    cryptor = AES.new(add_to_16(key), AES.MODE_CBC, iv.encode("utf-8"))
    encrypted_text = cryptor.encrypt(add_to_16(plaintext))
    encrypted_text = str(base64.encodebytes(encrypted_text), encoding="utf-8").replace(
        "\n", ""
    )
    return encrypted_text


def decrypt(ciphertext):
    key = "c07fc7174561aa91"
    iv = "c90866af49c1b68a"
    # 优先逆向解密base64成bytes
    cryptor = AES.new(add_to_16(key), AES.MODE_CBC, iv.encode("utf-8"))
    base64_decrypted = base64.decodebytes(ciphertext.encode())
    decrypted_text = cryptor.decrypt(base64_decrypted).decode("utf-8")
    decrypted_code = decrypted_text.rstrip("\0")
    return decrypted_code


# 取得当前系统时间17位字符串
def getNow():
    ct = time.time()  # 取得系统时间
    local_time = time.localtime(ct)
    date_head = time.strftime("%Y%m%d%H%M%S", local_time)  # 格式化时间
    date_m_secs = str(datetime.datetime.now().timestamp()).split(".")[
        -1
    ]  # 毫秒级时间戳
    time_stamp = "%s%.3s" % (date_head, date_m_secs)  # 拼接时间字符串
    return time_stamp


class UploadImgApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        category = request.POST["category"]
        print("category", category)
        file_obj = request.FILES["file"]
        print("file_obj", file_obj)
        file_name_suffix = file_obj.name.split(".")[-1]
        if file_name_suffix not in [
            "jpg",
            "png",
            "jpeg",
        ]:
            # /www/sites/cvms.qhduhu.com/waf/rules
            ret = {"code": 500, "msg": "错误的文件格式"}
            return Response(ret)
        upload_time = timezone.now()
        path = os.path.join(
            settings.MEDIA_ROOT,
            category,
            str(upload_time.year),
            str(upload_time.month),
            str(upload_time.day),
        )
        if not os.path.exists(path):
            os.makedirs(path)
        timestamp = getNow()
        file_name = timestamp + "." + file_name_suffix
        file_path = os.path.join(path, file_name)
        file_url = f"media/{category}/{upload_time.year}/{upload_time.month}/{upload_time.day}/{file_name}"
        if os.path.exists(file_path):
            ret = {"code": 500, "msg": "文件已存在", "url": file_url}
            return Response(ret)
        with open(file_path, "wb+") as f:
            for chunk in file_obj.chunks():
                f.write(chunk)
        ret = {"code": 0, "msg": "OK", "url": file_url}
        return Response(ret)


class IndexApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        # 管理员
        request_staff = request.user
        result["data"]["staff"] = StaffSerl(request_staff).data
        return Response(result)


class PlateSearchApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        # 管理员
        request_staff = request.user
        result["data"]["staff"] = StaffSerl(request_staff).data
        eplate = request.GET.get("eplate")
        print("eplate", eplate)
        number = decrypt(eplate)
        print("number", number)
        try:
            plate = Plate.objects.get(number=number)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        result["data"]["plate"] = PlateSerl(plate).data
        return Response(result)


class PlateSearchDecryptApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        # 管理员
        request_staff = request.user
        result["data"]["staff"] = StaffSerl(request_staff).data
        plateNumber = request.GET.get("plate")
        try:
            plate = Plate.objects.get(number=plateNumber)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        result["data"]["plate"] = PlateSerl(plate).data
        return Response(result)


class PlateDetApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        # 管理员
        request_staff = request.user
        result["data"]["staff"] = StaffSerl(request_staff).data
        plateid = request.GET.get("plateid")
        print("plateid", plateid)
        try:
            plate = Plate.objects.get(pk=plateid)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        result["data"]["plate"] = PlateSerl(plate).data
        try:
            car = Car.objects.get(plate=plate)
            result["data"]["car"] = CarSerl(car).data
            try:
                student = Student.objects.get(car=car)
                result["data"]["student"] = StudentSerl(student).data
            except Student.DoesNotExist:
                print("未绑定")
            try:
                teacher = Teacher.objects.get(car=car)
                result["data"]["teacher"] = TeacherSerl(teacher).data
            except Teacher.DoesNotExist:
                print("未绑定")
            # 违章
            violations = Violation.objects.filter(car=car)
            result["data"]["violations"] = ViolationListSerl(violations, many=True).data
        except Car.DoesNotExist:
            print("未绑定")
        return Response(result)


class PlateBindStudentApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        try:
            requestStaff = request.user
            result["data"]["staff"] = StaffSerl(requestStaff).data
        except Exception as e:
            print(e)
            return Response({"code": 403, "msg": "你没权限"})
        try:
            plateid = request.data["plateid"]
            brand = request.data["brand"]
            color = request.data["color"]
            is_ccc = request.data["is_ccc"]
            print("is_ccc", is_ccc)
            photos = request.data["photos"]
            college = request.data["college"]
            major = request.data["major"]
            grade = request.data["grade"]
            stuid = request.data["stuid"]
            name = request.data["name"]
            phone = request.data["phone"]
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            plate = Plate.objects.get(pk=plateid)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            car = Car()
            car.plate = plate
        car.brand = brand
        car.color = color
        car.is_ccc = is_ccc
        car.photos = photos
        car.kind = 0
        try:
            car.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "车辆保存失败"})
        try:
            student = Student.objects.get(car=car)
        except Student.DoesNotExist:
            student = Student()
            student.car = car
        student.college = college
        student.major = major
        student.grade = grade
        student.stuid = stuid
        student.name = name
        student.phone = phone
        try:
            student.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "学生保存失败"})
        plate.status = 1
        try:
            plate.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "牌照保存失败"})
        return Response(result)


class PlateBindTeacherApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        try:
            requestStaff = request.user
            result["data"]["staff"] = StaffSerl(requestStaff).data
        except Exception as e:
            print(e)
            return Response({"code": 403, "msg": "你没权限"})
        try:
            plateid = request.data["plateid"]
            brand = request.data["brand"]
            color = request.data["color"]
            is_ccc = request.data["is_ccc"]
            print("is_ccc", is_ccc)
            photos = request.data["photos"]
            dept = request.data["dept"]
            name = request.data["name"]
            phone = request.data["phone"]
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            plate = Plate.objects.get(pk=plateid)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            car = Car()
            car.plate = plate
        car.brand = brand
        car.color = color
        car.is_ccc = is_ccc
        car.photos = photos
        car.kind = 1
        try:
            car.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "车辆保存失败"})
        try:
            teacher = Teacher.objects.get(car=car)
        except Teacher.DoesNotExist:
            teacher = Teacher()
            teacher.car = car
        teacher.dept = dept
        teacher.name = name
        teacher.phone = phone
        try:
            teacher.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "教师保存失败"})
        plate.status = 1
        try:
            plate.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "牌照保存失败"})
        return Response(result)


class PlateResetStudentApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        try:
            requestStaff = request.user
            result["data"]["staff"] = StaffSerl(requestStaff).data
        except Exception as e:
            print(e)
            return Response({"code": 403, "msg": "你没权限"})
        try:
            plateid = request.data["plateid"]
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            plate = Plate.objects.get(pk=plateid)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            return Response({"code": 404, "msg": "车辆不存在"})
        try:
            student = Student.objects.get(car=car)
        except Student.DoesNotExist:
            print("学生不存在")
        try:
            student.delete()
        except Exception as e:
            print("学生删除失败")
            print(e)
        try:
            car.delete()
        except Exception as e:
            print("车辆删除失败")
            print(e)
        try:
            plate.status = 0
            plate.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "牌照保存失败"})
        return Response(result)


class PlateResetTeacherApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        try:
            requestStaff = request.user
            result["data"]["staff"] = StaffSerl(requestStaff).data
        except Exception as e:
            print(e)
            return Response({"code": 403, "msg": "你没权限"})
        try:
            plateid = request.data["plateid"]
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            plate = Plate.objects.get(pk=plateid)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "牌照不存在"})
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            return Response({"code": 404, "msg": "车辆不存在"})
        try:
            teacher = Teacher.objects.get(car=car)
        except Teacher.DoesNotExist:
            print("教师不存在")
        try:
            teacher.delete()
        except Exception as e:
            print("教师删除失败")
            print(e)
        try:
            car.delete()
        except Exception as e:
            print("车辆删除失败")
            print(e)
        try:
            plate.status = 0
            plate.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "牌照保存失败"})
        return Response(result)


class ViolationAddApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        try:
            requestStaff = request.user
            result["data"]["staff"] = StaffSerl(requestStaff).data
        except Exception as e:
            print(e)
            return Response({"code": 403, "msg": "你没权限"})
        try:
            carId = request.data["carId"]
            reason = request.data["reason"]
            photos = request.data["photos"]
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            car = Car.objects.get(pk=carId)
        except Plate.DoesNotExist:
            return Response({"code": 404, "msg": "车辆不存在"})
        try:
            violation = Violation()
            violation.car = car
            violation.reason = reason
            violation.photos = photos
            violation.staff = requestStaff
            violation.save()
        except Exception as e:
            print(e)
            return Response({"code": 500, "msg": "违规记录保存失败"})
        return Response(result)


class ViolationDetApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [BikeJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        # 管理员
        request_staff = request.user
        result["data"]["staff"] = StaffSerl(request_staff).data
        # 获取查询参数
        try:
            violationId = request.GET.get("violationId")
        except Exception:
            return Response({"code": 403, "msg": "参数错误"})
        try:
            violation = Violation.objects.get(pk=violationId)
        except Violation.DoesNotExist:
            return Response({"code": 404, "msg": "违章不存在"})
        result["data"]["violation"] = ViolationSerl(violation).data
        return Response(result)
